/*
 * ClientConnect.cpp
 *
 *  Created on: Aug 17, 2016
 *      Author: ubuntu
 */

#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "Conf.h"
#include "DBManager.h"
#include "ClientConnect.h"

ClientConnection::ClientConnection(TcpServer *pParent, struct connectop *op, struct sockaddr *addr)
{
	m_pParent = pParent;
	m_fd = op->fd;
	m_addr = *addr;
	m_bTerminated = false;
	m_op = op;
	tm_conn = time(NULL);
	tm_last = time(NULL);
	add_head = ADD_HEAD;
	add_tail = ADD_TAIL;
	add_len = add_head + add_tail;
}

ClientConnection::~ClientConnection()
{
}

void ClientConnection::on_read()
{
	int to_alloc = MIN_MALLOC_SIZE;  // 分配的用于存储接收数据的内存块大小
	int n,  nread, r_errno;
	unsigned char *buf = (unsigned char *)malloc(to_alloc + add_len);
	if (!buf)
		return;
	n = 0;
	while (1) {
		/* 重新分配内存存储更多的数据 */
		if (n >= to_alloc) {
			to_alloc *= 2;
			unsigned char *tmp = (unsigned char *)realloc(buf, to_alloc+add_len);
			if (!tmp) {
				debug(LOG_ERR, "realloc failed: %s", strerror(errno));
				exit(1);
			} else {
				buf = tmp;
			}
		}
		nread = read(m_fd, buf+n+add_head, to_alloc-n);
		if (nread == 0) {
			break;
		} else if (nread < 0) {
			r_errno = errno;
			break;
		}
		n += nread;
	}
	if (n > 0) {
		tm_last = time(NULL);
		if (nread == 0) {
			close(m_fd);
			m_fd = -1;
		} else if (nread < 0 && r_errno != EAGAIN) {
			close(m_fd);
			m_fd = -1;
		}
		if (parsePackage(buf, n, add_head, add_tail) == false) {
			free(buf);
		}
		if (m_fd < 0)
			m_pParent->on_close(this);
	} else {
		free(buf);
		m_pParent->on_close(this);
	}
}

bool ClientConnection::parsePackage(unsigned char *buf, size_t len, int add_head, int add_tail)
{
	unsigned char *pBuf = buf + add_head;
	if (add_tail > 0) {
		pBuf[len] = 0;
	}
	debug(LOG_DEBUG, "消息: [%s]", pBuf);
	free(buf);
	return true;
}

void ClientConnection::on_close()
{
	epoll_ctl(m_op->epfd, EPOLL_CTL_DEL, m_fd, NULL);
	if (m_fd > 0)
		close(m_fd);
	if (m_op) {
		free(m_op);
	}
}

void ClientConnection::sendBuf(unsigned char *buf, size_t len)
{
	if (m_fd < 0)
		return;
	if (write(m_fd, buf, len) < 0) {
		m_pParent->on_close(this);
	}
	size_t k = len * 2 + 1;
#if 1
	char *tbuf = (char *)malloc(k);
	if (tbuf) {
		for (size_t i = 0; i < len; i++)
			sprintf(tbuf+i*2, "%02X", buf[i]);
		debug(LOG_DEBUG, "BIN:\n%s", tbuf);
		free(tbuf);
	}
#endif
}

time_t ClientConnection::getLastTime()
{
	return tm_last;
}

time_t ClientConnection::getConnTime()
{
	return tm_conn;
}

void ClientConnection::recv_data_output(unsigned char *buf, size_t len)
{
	char *tmp = (char *)malloc(len * 2 + 1);
	if (tmp) {
		for (size_t i = 0; i < len; i++)
			sprintf(tmp+i*2, "%02X", buf[i]);
		debug(LOG_DEBUG, "消息: [%s]", tmp);
		free(tmp);
	}
}

void ClientConnection::pushDataInfo(DataInfo *pDataInfo)
{
	DBManager *pManager = getConf()->pManager;
	if (pManager) {
		pManager->push(pDataInfo);
	} else {
		debug(LOG_DEBUG, "不可能有这种事情发生");
		exit(1);
	}
}
